package spring.cloud.tasks.executor.name_space.executor.task.task_item;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import spring.cloud.tasks.executor.utils.LogUtils;

@Slf4j
@Setter
@Getter
class TaskItemExecuteTimeoutTask implements Runnable {

    private String threadName;

    public TaskItemExecuteTimeoutTask(String threadName) {
        this.threadName = threadName;
    }


    @Override
    public void run() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                timeOut(threadName);
            }
        }).start();
    }

    private void timeOut(String threadName) {
        try {
            Thread thread = getThreadByName(threadName);
            if (thread != null) {
                TaskItemExecuteThread taskItemExecuteThread = (TaskItemExecuteThread) thread;
                TaskItemExecuteTask taskItemExecuteTask = taskItemExecuteThread.getTaskItemExecuteTask();
                if (taskItemExecuteTask != null) {
                    TaskItemExecute taskItemExecute = taskItemExecuteTask.getTaskItemExecute();
                    if (taskItemExecute != null) {
                        if (taskItemExecute.setTimeoutWhenStatusInit()) {
                            String taskId = taskItemExecute.getTaskId();
                            Integer taskItemIndex = taskItemExecute.getTaskItemIndex();
                            LogUtils.info(log, taskId, "Force stop timeout job, taskId:{}, item:{}", taskId, taskItemIndex);
                            // 强杀
                            TaskItemExecuteTaskKill.kill(taskItemExecuteTask);
                        }
                    }

                }

            }

        } catch (Throwable t) {
            LogUtils.warn(log, "unknown job", "Failed to force stop timeout job", t);
        }
    }

    public Thread getThreadByName(String threadName) {
        for (Thread thread : Thread.getAllStackTraces().keySet()) {
            if (thread.getName().equals(threadName)) {

                return thread;
            }
        }
        return null;
    }

}
